#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#include "../../SCVector.h"

#define DEF_N_TESTS 10000
#define DEF_MAX_VAL  1000


int main(int argc, char *argv[])
{
  unsigned int ntests  = DEF_N_TESTS;
  unsigned int max_val = DEF_MAX_VAL;
  unsigned int i;
  unsigned int j;
  unsigned int val;
  SCVector<unsigned int> vals;
  SCVector<unsigned int> inserted;
  SCVector<unsigned int> postsort;

  srand((unsigned int)time(0));

  if(argc > 1)
  {
    if(strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "/?") == 0 ||
       strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "/h") == 0 ||
       strcmp(argv[1], "-H") == 0 || strcmp(argv[1], "/H") == 0 ||
       strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "/help") == 0)
    {
      printf("%s <n numbers to test> <max random value> <number to pass to srand()>\n", argv[0]);
      return 0;
    }

    ntests = atoi(argv[1]);
    if(!ntests)
      ntests = 1;
  }

  if(argc > 2)
  {
    max_val = atoi(argv[2]);
    if(!max_val)
      max_val = 1;
  }

  if(argc > 3)
    srand(atoi(argv[3]));

  printf("Populating Vectors : ");
  vals.reserve(ntests);
  inserted.reserve(ntests);
  postsort.reserve(ntests);
  for(i = 0; i < ntests; ++i)
  {
    val = (rand() % max_val) + 1;
    vals.push_back(val);
    inserted.insert(val);
    postsort.push_back(val);
  }
  printf("Done\n");

  printf("Post Sorting a Vec : ");
  postsort.sort();
  printf("Done\n");


  printf("Sort Integrity Test: ");
  if(inserted[0] != postsort[0])
  {
    printf("Error:%3d: Not Correctly Sorted: %d != %d\n", __LINE__, inserted[0], postsort[0]);
    return 0;
  }

  for(i = 1; i < ntests; ++i)
  {
    if(inserted[i - 1] > inserted[i])
    {
      printf("Error:%3d: Not Correctly Sorted.\n", __LINE__);
      return 0;
    }

    if(inserted[i] != postsort[i])
    {
      printf("Error:%3d: Not Correctly Sorted.\n", __LINE__);
      return 0;
    }
  }
  printf("Done\n");


  printf("Looking for lost # : ");
  for(i = 0; i < ntests; ++i)
  {
    for(j = 0; j < ntests; ++j)
      if(vals[i] == inserted[j])
      {
        inserted[j] = 0;
        break;
      }

    if(j >= ntests)
    {
      printf("Error:%3d: Lost the value: %d\n", __LINE__, vals[i]);
      return 0;
    }
  }
  printf("Done\n");


  printf("Validating find*() : ");
  for(i = 0; i < ntests; ++i)
  {
    if(postsort.find_index(vals[i]) == ~static_cast<unsigned int>(0))
    {
      printf("Error:%3d: Could not find the element: %d\n", __LINE__, vals[i]);
      return 0;
    }

    if(postsort.find(vals[i]) == 0)
    {
      printf("Error:%3d: Could not find the element: %d\n", __LINE__, vals[i]);
      return 0;
    }

    if(postsort.find_first(vals[i]) == 0)
    {
      printf("Error:%3d: Could not find the element: %d\n", __LINE__, vals[i]);
      return 0;
    }

    if(postsort.find_all(vals[i]).size() == 0)
    {
      printf("Error:%3d: Could not find the element: %d\n", __LINE__, vals[i]);
      return 0;
    }
  }
  printf("Done\n");

  printf("No Error Found\n");

  return 0;
}
